﻿/*************************************************************************************
 * 工    具：  HK_CheckUITexturePath
 * 
 * 描    述：  HK_CheckUITexturePath 工具，用于检查当前Scene场景中所有UI图片（Image/RawImage组件）的资源路径。
 *            支持按资源根文件夹分组展示路径信息，显示每个路径关联的UI组件数量。
 *            点击路径条目可快速选中关联的游戏对象并在Hierarchy视图中高亮显示。
 *            工具支持在Light和Dark主题下自适应显示效果。
 *            主要用于 WebGL 等项目，用于集中管理及优化UI图集。
 * 
 * 版    本：  V1.0
 * 作    者：  京产肠饭
 * 
 * 创    建：  2025/06/11  V1.0
 * 
 * 链    接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

namespace HKTools
{
    /// <summary>
    /// 检查当前场景中所有UI图片的路径
    /// </summary>
    public class HK_CheckUITexturePath : EditorWindow
    {
        Dictionary<string, Dictionary<string, List<Component>>> textureGroups;  // 根文件夹→路径→组件列表

        Vector2 scrollPosition; // 滚动视图位置状态

        // 添加菜单入口
        [MenuItem("HKTools/Check UI Textures Path（UI图片路径检查工具）", priority = HK_MenuPriority.HK_CheckUITexturePath)]
        public static void ShowWindow()
        {
            GetWindow<HK_CheckUITexturePath>("UI图片路径检查");
        }

        // 绘制窗口界面
        void OnGUI()
        {
            EditorGUILayout.Space();

            // 自定义带居中对齐的帮助框样式
            GUIStyle centeredHelpBoxStyle = new GUIStyle(EditorStyles.helpBox)
            {
                alignment = TextAnchor.MiddleLeft // 文字垂直居中
            };

            // 绘制一个工具提示（增加高度并居中文字）
            EditorGUILayout.LabelField("注意：此工具用于检查当前Scene场景中的UI图片路径", centeredHelpBoxStyle, GUILayout.Height(26));

            EditorGUILayout.Space();

            // 检查按钮（增加高度到30像素）
            if (GUILayout.Button("检查当前场景UI图片路径", GUILayout.Height(26)))
            {
                CheckTexturePaths();
            }

            // 开始滚动视图（仅包裹内容区域，保持按钮固定）
            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
            {
                if (textureGroups != null)
                {
                    if (textureGroups.Count == 0)
                    {
                        EditorGUILayout.LabelField("未找到有效UI图片资源");
                        // 移除原return语句，避免提前退出导致滚动视图未关闭
                    }
                    else
                    {
                        // 定义超链接样式（根据主题动态调整颜色）
                        GUIStyle linkStyle = new GUIStyle(EditorStyles.label)
                        {
                            normal = { textColor = EditorGUIUtility.isProSkin ? Color.white : Color.black }, // Dark主题用白色，Light主题用黑色
                            hover = { textColor = EditorGUIUtility.isProSkin ? Color.cyan : Color.blue },   // Dark主题用青色，Light主题用蓝色
                            stretchWidth = false
                        };

                        foreach (var group in textureGroups)
                        {
                            EditorGUILayout.LabelField($"根文件夹: {group.Key}", EditorStyles.boldLabel);

                            EditorGUILayout.Space(2);

                            foreach (var pathEntry in group.Value)
                            {
                                string path = pathEntry.Key;
                                int componentCount = pathEntry.Value.Count;

                                GUILayout.BeginHorizontal();
                                if (GUILayout.Button($"{path} ({componentCount}个组件)", linkStyle))
                                {
                                    // 过滤已销毁的组件
                                    var validComponents = pathEntry.Value.Where(c => c != null).ToList();
                                    if (validComponents.Count > 0)
                                    {
                                        // 选中所有关联的游戏对象
                                        Selection.objects = validComponents.Select(c => c.gameObject).ToArray();
                                        // 在Hierarchy中高亮第一个对象
                                        EditorGUIUtility.PingObject(validComponents[0].gameObject);
                                    }
                                }
                                GUILayout.EndHorizontal();
                            }

                            EditorGUILayout.Space(10);
                        }
                    }
                }
            }
            EditorGUILayout.EndScrollView(); // 确保滚动视图关闭
        }

        // 核心检查逻辑
        void CheckTexturePaths()
        {
            textureGroups = new Dictionary<string, Dictionary<string, List<Component>>>();

            var images = Resources.FindObjectsOfTypeAll<Image>();
            var rawImages = Resources.FindObjectsOfTypeAll<RawImage>();

            foreach (var img in images)
            {
                if (img.sprite != null)
                {
                    string path = AssetDatabase.GetAssetPath(img.sprite);
                    AddComponentToPathGroup(path, img);
                }
            }

            foreach (var rawImg in rawImages)
            {
                if (rawImg.texture != null)
                {
                    string path = AssetDatabase.GetAssetPath(rawImg.texture);
                    AddComponentToPathGroup(path, rawImg);
                }
            }
        }

        void AddComponentToPathGroup(string path, Component component)
        {
            if (string.IsNullOrEmpty(path) || !path.StartsWith("Assets/")) return;

            string[] pathParts = path.Split('/');
            if (pathParts.Length < 2) return;

            string rootFolder = pathParts[1];

            // 初始化根文件夹分组
            if (!textureGroups.ContainsKey(rootFolder))
                textureGroups[rootFolder] = new Dictionary<string, List<Component>>();

            // 初始化路径对应的组件列表
            if (!textureGroups[rootFolder].ContainsKey(path))
                textureGroups[rootFolder][path] = new List<Component>();

            // 避免重复添加同一组件
            if (!textureGroups[rootFolder][path].Contains(component))
                textureGroups[rootFolder][path].Add(component);
        }
    }
}